[[package]]
name = "flate2"
version = "0.0.1"
-source = "git+https://github.com/alexcrichton/flate2-rs#f74a1f632c09e4f241ecb638e331c2cec4e955e0"
+source = "git+https://github.com/alexcrichton/flate2-rs#67be37548937c059370ce272efe1142fbf198d67"
[[package]]
name = "git2"
version = "0.0.1"
-source = "git+https://github.com/alexcrichton/git2-rs#fc308a305068392b07999b7c47122244b151cdec"
+source = "git+https://github.com/alexcrichton/git2-rs#35a0632e92d63de8218675a17cd81e15d0de44b4"
dependencies = [
"libgit2 0.0.1 (git+https://github.com/alexcrichton/git2-rs)",
"url 0.1.0 (git+https://github.com/servo/rust-url)",
[[package]]
name = "libgit2"
version = "0.0.1"
-source = "git+https://github.com/alexcrichton/git2-rs#fc308a305068392b07999b7c47122244b151cdec"
+source = "git+https://github.com/alexcrichton/git2-rs#35a0632e92d63de8218675a17cd81e15d0de44b4"
dependencies = [
"libssh2-static-sys 0.0.1 (git+https://github.com/alexcrichton/libssh2-static-sys)",
"link-config 0.0.1 (git+https://github.com/alexcrichton/link-config)",
[[package]]
name = "link-config"
version = "0.0.1"
-source = "git+https://github.com/alexcrichton/link-config#ed9fffa15fc41e8f09e92c7756feead1b0cbb01d"
+source = "git+https://github.com/alexcrichton/link-config#7c56ef12c8a49bedb0357e2a50af9ba79bf0ae1b"
[[package]]
name = "openssl-static-sys"
[[package]]
name = "semver"
version = "0.1.0"
-source = "git+https://github.com/rust-lang/semver#fdaec35ff5db609f53119f1e455fdd8830edc790"
+source = "git+https://github.com/rust-lang/semver#7dca047a9cd40e929a4545b37a1917daff82f156"
[[package]]
name = "tar"
version = "0.0.1"
-source = "git+https://github.com/alexcrichton/tar-rs#fced2e3833ed2776d9975ffc6fb3204528944faa"
+source = "git+https://github.com/alexcrichton/tar-rs#47d2cc4b09e373a4cc7bee7c71ebf96b42ea620d"
[[package]]
name = "toml"
version = "0.1.0"
-source = "git+https://github.com/alexcrichton/toml-rs#35804927ef76cc5f24b04f2af25919c488a0992c"
+source = "git+https://github.com/alexcrichton/toml-rs#71d1689d63ef1af41addef330e314a56e88f48a9"
[[package]]
name = "url"
Some(err) => {
Err(match err.exit {
Some(ExitStatus(i)) => CliError::new("", i as uint),
- _ => CliError::from_boxed(err.mark_human(), 101)
+ _ => CliError::from_boxed(err.concrete().mark_human(), 101)
})
}
}
Some(err) => {
Err(match err.exit {
Some(ExitStatus(i)) => CliError::new("", i as uint),
- _ => CliError::from_boxed(err.mark_human(), 101)
+ _ => CliError::from_boxed(err.concrete().mark_human(), 101)
})
}
}
-use term::{mod, Terminal, color};
+use term::{Terminal, TerminfoTerminal, color};
use term::color::{Color, BLACK, RED, GREEN, YELLOW};
use term::attr::{Attr, Bold};
use std::io::{IoResult, stderr};
pub tty: bool
}
-enum AdequateTerminal<'a> {
- NoColor(Box<Writer+'a>),
- Colored(Box<Terminal<Box<Writer+'a>>+'a>)
+enum AdequateTerminal {
+ NoColor(Box<Writer + Send>),
+ Colored(Box<Terminal<UghWhyIsThisNecessary> + Send>)
}
-pub struct Shell<'a> {
- terminal: AdequateTerminal<'a>,
- config: ShellConfig
+pub struct Shell {
+ terminal: AdequateTerminal,
+ config: ShellConfig,
}
-pub struct MultiShell<'a> {
- out: Shell<'a>,
- err: Shell<'a>,
+pub struct MultiShell {
+ out: Shell,
+ err: Shell,
verbose: bool
}
pub type Callback<'a> = |&mut MultiShell|:'a -> IoResult<()>;
-impl<'a> MultiShell<'a> {
- pub fn new(out: Shell<'a>, err: Shell<'a>, verbose: bool) -> MultiShell<'a> {
+struct UghWhyIsThisNecessary {
+ inner: Box<Writer + Send>,
+}
+
+impl MultiShell {
+ pub fn new(out: Shell, err: Shell, verbose: bool) -> MultiShell {
MultiShell { out: out, err: err, verbose: verbose }
}
- pub fn out(&mut self) -> &mut Shell<'a> {
+ pub fn out(&mut self) -> &mut Shell {
&mut self.out
}
- pub fn err(&mut self) -> &mut Shell<'a> {
+ pub fn err(&mut self) -> &mut Shell {
&mut self.err
}
}
}
-pub type ShellCallback<'a> = |&mut Shell<'a>|:'a -> IoResult<()>;
+pub type ShellCallback<'a> = |&mut Shell|:'a -> IoResult<()>;
-impl<'a> Shell<'a> {
- pub fn create(out: Box<Writer+'a>, config: ShellConfig) -> Shell<'a> {
+impl Shell {
+ pub fn create(out: Box<Writer + Send>, config: ShellConfig) -> Shell {
+ let out = UghWhyIsThisNecessary { inner: out };
if config.tty && config.color {
- let term: Option<term::TerminfoTerminal<Box<Writer+'a>>> = Terminal::new(out);
+ let term = TerminfoTerminal::new(out);
term.map(|t| Shell {
- terminal: Colored(box t as Box<Terminal<Box<Writer+'a>>>),
+ terminal: Colored(t),
config: config
}).unwrap_or_else(|| {
- Shell { terminal: NoColor(box stderr() as Box<Writer+'a>), config: config }
+ Shell { terminal: NoColor(box stderr()), config: config }
})
} else {
- Shell { terminal: NoColor(out), config: config }
+ Shell { terminal: NoColor(out.inner), config: config }
}
}
try!(self.flush());
Ok(())
}
-}
-
-impl<'a> Terminal<Box<Writer+'a>> for Shell<'a> {
- fn new(out: Box<Writer+'a>) -> Option<Shell<'a>> {
- Some(Shell {
- terminal: NoColor(out),
- config: ShellConfig {
- color: true,
- verbose: false,
- tty: false,
- }
- })
- }
fn fg(&mut self, color: color::Color) -> IoResult<bool> {
match self.terminal {
}
}
- fn bg(&mut self, color: color::Color) -> IoResult<bool> {
- match self.terminal {
- Colored(ref mut c) => c.bg(color),
- NoColor(_) => Ok(false)
- }
- }
-
fn attr(&mut self, attr: Attr) -> IoResult<bool> {
match self.terminal {
Colored(ref mut c) => c.attr(attr),
NoColor(_) => Ok(())
}
}
-
- fn unwrap(self) -> Box<Writer+'a> {
- panic!("Can't unwrap a Shell");
- }
-
- fn get_ref<'b>(&'b self) -> &'b Box<Writer+'a> {
- match self.terminal {
- Colored(ref c) => c.get_ref(),
- NoColor(ref w) => w
- }
- }
-
- fn get_mut<'b>(&'b mut self) -> &'b mut Box<Writer+'a> {
- match self.terminal {
- Colored(ref mut c) => c.get_mut(),
- NoColor(ref mut w) => w
- }
- }
}
-impl<'a> Writer for Shell<'a> {
+impl Writer for Shell {
fn write(&mut self, buf: &[u8]) -> IoResult<()> {
match self.terminal {
Colored(ref mut c) => c.write(buf),
}
}
}
+
+impl Writer for UghWhyIsThisNecessary {
+ fn write(&mut self, bytes: &[u8]) -> IoResult<()> {
+ self.inner.write(bytes)
+ }
+}
}
}
-pub fn shell(verbose: bool) -> MultiShell<'static> {
+pub fn shell(verbose: bool) -> MultiShell {
let tty = stderr_raw().isatty();
- let stderr = box stderr() as Box<Writer>;
+ let stderr = box stderr() as Box<Writer + Send>;
let config = ShellConfig { color: true, verbose: verbose, tty: tty };
let err = Shell::create(stderr, config);
let tty = stdout_raw().isatty();
- let stdout = box stdout() as Box<Writer>;
+ let stdout = box stdout() as Box<Writer + Send>;
let config = ShellConfig { color: true, verbose: verbose, tty: tty };
let out = Shell::create(stdout, config);
pub struct CleanOptions<'a> {
pub spec: Option<&'a str>,
pub target: Option<&'a str>,
- pub shell: &'a mut MultiShell<'a>
+ pub shell: &'a mut MultiShell,
}
/// Cleans the project from build artifacts.
/// Contains informations about how a package should be compiled.
pub struct CompileOptions<'a> {
pub env: &'a str,
- pub shell: &'a mut MultiShell<'a>,
+ pub shell: &'a mut MultiShell,
/// Number of concurrent jobs to use.
pub jobs: Option<uint>,
/// The target platform to compile for (example: `i686-unknown-linux-gnu`).
use util::{CargoResult, human};
pub struct UpdateOptions<'a> {
- pub shell: &'a mut MultiShell<'a>,
+ pub shell: &'a mut MultiShell,
pub to_update: Option<&'a str>,
pub precise: Option<&'a str>,
pub aggressive: bool,
use std::io::fs::PathExtensions;
use core::{Package,Manifest,SourceId};
-use util::{mod, CargoResult, human, CargoError};
+use util::{mod, CargoResult, human, FromError};
use util::important_paths::find_project_manifest_exact;
use util::toml::{Layout, project_layout};
let dirs = match fs::readdir(path) {
Ok(dirs) => dirs,
Err(ref e) if e.kind == io::PermissionDenied => return Ok(()),
- Err(e) => return Err(e.box_error()),
+ Err(e) => return Err(FromError::from_error(e)),
};
for dir in dirs.iter() {
try!(walk(dir, false, |a, x| callback(a, x)))
self.active -= 1;
match result {
Ok(()) => {
- let state = self.pending.get_mut(&(id, stage));
+ let state = &mut self.pending[(id, stage)];
state.amt -= 1;
state.fresh = state.fresh.combine(fresh);
if state.amt == 0 {
try!(p.exec_with_output().map(|_| ()).map_err(|mut e| {
e.msg = format!("Failed to run custom build command for `{}`\n{}",
pkg, e.msg);
- e.mark_human()
+ e.concrete().mark_human()
}));
Ok(())
})
pub struct Config<'a> {
home_path: Path,
- shell: &'a mut MultiShell<'a>,
+ shell: &'a mut MultiShell,
jobs: uint,
target: Option<string::String>,
linker: Option<string::String>,
if fresh == Dirty {
self.dirty.insert(dep.clone());
}
- assert!(self.dep_map.get_mut(dep).mut0().remove(key));
+ assert!(self.dep_map[*dep].mut0().remove(key));
}
}
}
fn cause(&self) -> Option<&CargoError> { None }
fn is_human(&self) -> bool { false }
- fn to_error<E: FromError<Self>>(self) -> E {
- FromError::from_error(self)
- }
-
- fn box_error(self) -> Box<CargoError + Send> {
- box self as Box<CargoError + Send>
- }
-
fn concrete(&self) -> ConcreteCargoError {
ConcreteCargoError {
description: self.description(),
is_human: self.is_human()
}
}
-
- fn with_cause<E: CargoError + Send>(self, cause: E) -> Box<CargoError + Send> {
- let mut concrete = self.concrete();
- concrete.cause = Some(cause.box_error());
- box concrete as Box<CargoError + Send>
- }
-
- fn mark_human(self) -> Box<CargoError + Send> {
- let mut concrete = self.concrete();
- concrete.is_human = true;
- box concrete as Box<CargoError + Send>
- }
}
pub trait FromError<E> {
impl<E: CargoError + Send> FromError<E> for Box<CargoError + Send> {
fn from_error(error: E) -> Box<CargoError + Send> {
- error.box_error()
+ box error as Box<CargoError + Send>
}
}
}
impl CargoError for Box<CargoError + Send> {
- fn description(&self) -> String {
- (**self).description()
- }
-
- fn detail(&self) -> Option<String> {
- (**self).detail()
- }
-
- fn cause(&self) -> Option<&CargoError> {
- (**self).cause()
- }
-
- fn is_human(&self) -> bool {
- (**self).is_human()
- }
-
- fn box_error(self) -> Box<CargoError + Send> {
- self
- }
+ fn description(&self) -> String { (**self).description() }
+ fn detail(&self) -> Option<String> { (**self).detail() }
+ fn cause(&self) -> Option<&CargoError> { (**self).cause() }
+ fn is_human(&self) -> bool { (**self).is_human() }
}
impl CargoError for semver::ReqParseError {
impl<'a, T> ChainError<T> for ||:'a -> CargoResult<T> {
fn chain_error<E: CargoError + Send>(self, callback: || -> E) -> CargoResult<T> {
- self().map_err(|err| callback().with_cause(err))
+ self().map_err(|err| callback().concrete().with_cause(err))
}
}
impl<T, E: CargoError + Send> BoxError<T> for Result<T, E> {
fn box_error(self) -> CargoResult<T> {
- self.map_err(|err| err.box_error())
+ self.map_err(|err| box err as Box<CargoError + Send>)
}
}
impl<T, E: CargoError + Send> ChainError<T> for Result<T, E> {
fn chain_error<E: CargoError + Send>(self, callback: || -> E) -> CargoResult<T> {
- self.map_err(|err| callback().with_cause(err))
+ self.map_err(|err| callback().concrete().with_cause(err))
}
}
fn cause(&self) -> Option<&CargoError> {
self.cause.as_ref().map(|c| { let err: &CargoError = &**c; err })
}
-
- fn with_cause<E: CargoError + Send>(mut self,
- err: E) -> Box<CargoError + Send> {
- self.cause = Some(err.box_error());
- box self as Box<CargoError + Send>
- }
}
pub struct ConcreteCargoError {
is_human: bool
}
+impl ConcreteCargoError {
+ pub fn with_cause<E: CargoError + Send>(mut self,
+ err: E) -> Box<CargoError + Send> {
+ self.cause = Some(box err as Box<CargoError + Send>);
+ box self as Box<CargoError + Send>
+ }
+
+ pub fn mark_human(mut self) -> Box<CargoError + Send> {
+ self.is_human = true;
+ box self as Box<CargoError + Send>
+ }
+}
+
impl Show for ConcreteCargoError {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "{}", self.description)
self.cause.as_ref().map(|c| { let err: &CargoError = &**c; err })
}
- fn with_cause<E: CargoError + Send>(mut self,
- err: E) -> Box<CargoError + Send> {
- self.cause = Some(err.box_error());
- box self as Box<CargoError + Send>
- }
-
- fn mark_human(mut self) -> Box<CargoError + Send> {
- self.is_human = true;
- box self as Box<CargoError + Send>
- }
-
fn is_human(&self) -> bool {
self.is_human
}
box ConcreteCargoError {
description: error.to_string(),
detail: None,
- cause: Some(cause.box_error()),
+ cause: Some(box cause as Box<CargoError + Send>),
is_human: true
} as Box<CargoError + Send>
}
fn wrap<E: CargoError + Send>(self, error: E) -> CargoResult<T> {
match self {
Ok(x) => Ok(x),
- Err(e) => Err(error.with_cause(e))
+ Err(e) => Err(error.concrete().with_cause(e))
}
}
}
-use support::{ResultTest,Tap,shell_writes};
+use std::io::{MemWriter, IoResult, ChanReader, ChanWriter};
+use term::{Terminal, TerminfoTerminal, color};
use hamcrest::{assert_that};
-use std::io::{MemWriter, BufWriter, IoResult};
+
use cargo::core::shell::{Shell,ShellConfig};
-use term::{Terminal,TerminfoTerminal,color};
+
+use support::{ResultTest,Tap,shell_writes};
fn setup() {
}
-fn writer(buf: &mut [u8]) -> Box<Writer> {
- box BufWriter::new(buf) as Box<Writer>
+fn pair() -> (ChanWriter, ChanReader) {
+ let (tx, rx) = channel();
+ (ChanWriter::new(tx), ChanReader::new(rx))
}
test!(non_tty {
let config = ShellConfig { color: true, verbose: true, tty: false };
- let mut buf: Vec<u8> = Vec::from_elem(9, 0 as u8);
+ let (tx, mut rx) = pair();
- Shell::create(writer(buf.as_mut_slice()), config).tap(|shell| {
+ Shell::create(box tx, config).tap(|shell| {
shell.say("Hey Alex", color::RED).assert();
- assert_that(buf.as_slice(), shell_writes("Hey Alex\n"));
});
+
+ let buf = rx.read_to_end().unwrap();
+ assert_that(buf.as_slice(), shell_writes("Hey Alex\n"));
})
test!(color_explicitly_disabled {
let config = ShellConfig { color: false, verbose: true, tty: true };
- let mut buf: Vec<u8> = Vec::from_elem(9, 0 as u8);
+ let (tx, mut rx) = pair();
- Shell::create(writer(buf.as_mut_slice()), config).tap(|shell| {
+ Shell::create(box tx, config).tap(|shell| {
shell.say("Hey Alex", color::RED).assert();
- assert_that(buf.as_slice(), shell_writes("Hey Alex\n"));
});
+ let buf = rx.read_to_end().unwrap();
+ assert_that(buf.as_slice(), shell_writes("Hey Alex\n"));
})
test!(colored_shell {
- let term: Option<TerminfoTerminal<MemWriter>> =
- Terminal::new(MemWriter::new());
+ let term = TerminfoTerminal::new(MemWriter::new());
if term.is_none() { return }
let config = ShellConfig { color: true, verbose: true, tty: true };
- let mut buf: Vec<u8> = Vec::from_elem(100, 0 as u8);
+ let (tx, mut rx) = pair();
- Shell::create(writer(buf.as_mut_slice()), config).tap(|shell| {
+ Shell::create(box tx, config).tap(|shell| {
shell.say("Hey Alex", color::RED).assert();
- let buf = buf.as_slice().slice_to(buf.iter().position(|a| *a == 0).unwrap());
- assert_that(buf, shell_writes(colored_output("Hey Alex\n",
- color::RED).assert()));
});
+ let buf = rx.read_to_end().unwrap();
+ assert_that(buf.as_slice(),
+ shell_writes(colored_output("Hey Alex\n",
+ color::RED).assert()));
})
fn colored_output<S: Str>(string: S, color: color::Color) -> IoResult<String> {
- let mut term: TerminfoTerminal<MemWriter> =
- Terminal::new(MemWriter::new()).assert();
+ let mut term = TerminfoTerminal::new(MemWriter::new()).unwrap();
try!(term.reset());
try!(term.fg(color));
try!(term.write_str(string.as_slice()));